package vip.xiaonuo.modular.manage.tsdatarecord.parser;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import org.springframework.stereotype.Component;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.modular.file.util.CommonFileUtils;
import vip.xiaonuo.modular.manage.tsdatarecord.entity.BaseMetadata;
import vip.xiaonuo.modular.manage.tsdatarecord.enums.FileParseExceptionEnum;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.*;
import java.util.function.Consumer;

/**
 * CsvFileParser
 *
 * @author JackLee
 * 2022/8/9 11:19
 */
@Component
@Slf4j
public class CsvFileParser implements FileParser {
    @Override
    public boolean available(String extension) {
        return CommonFileUtils.FileType.CSV.equals(extension);
    }

    @Override
    public ParserResult parse(String filePath, Integer dealSize, String recordId, Consumer<List<BaseMetadata>> consumer) {
        ParserResult parserResult = new ParserResult();
        List<TableColumn> tableSchemas = new ArrayList<>();
        if (dealSize == null || dealSize < 1) {
            dealSize = 1000;
        }
        List<BaseMetadata> dataList = new ArrayList<>(dealSize);
        String intoDate = DateUtil.now();
        Reader reader = null;
        try {
            reader = new FileReader(filePath);
            Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(reader);
            Iterator<CSVRecord> recordIterator = records.iterator();
            int i = 0;
            int j = 0;
            int total = 0;
            //首行 表头
            if (recordIterator.hasNext()) {
                CSVRecord headRecord = recordIterator.next();
                Iterator<String> values = headRecord.iterator();
                while (values.hasNext()) {
                    j++;
                    String value = values.next();
                    TableColumn column = new TableColumn();
                    column.setTitle(value);
                    column.setSort(j);
                    column.setDataIndex("index" + j);
                    tableSchemas.add(column);
                }
                j = 0;
            }
            // 获取数据
            while (recordIterator.hasNext()) {
                CSVRecord record = recordIterator.next();
                i++;
                total++;
                Iterator<String> values = record.iterator();
                Map<String, String> data = new HashMap<>();
                while (values.hasNext()) {
                    j++;
                    String value = values.next();
                    data.put("index" + j, value);
                }
                BaseMetadata metadata = new BaseMetadata(recordId, JSON.toJSONString(data), intoDate);
                dataList.add(metadata);
                j = 0;
                if (i == dealSize) {
                    consumer.accept(dataList);
                    dataList = new ArrayList<>(dealSize);
                    i = 0;
                }
            }
            if (dataList.size() > 0) {
                consumer.accept(dataList);
            }
            parserResult.setColumnList(tableSchemas);
            parserResult.setTotalCount(total);
            log.info("{}文件解析完成！", filePath);
            return parserResult;
        } catch (FileNotFoundException e) {
            log.error("文件不存在：{}", filePath);
            throw new ServiceException(FileParseExceptionEnum.NOT_EXIST);
        } catch (IOException e) {
            log.error(recordId + ">>> 文件解析失败！", e);
            throw new ServiceException(FileParseExceptionEnum.FILE_PARSE_ERROR);
        } finally {
            IoUtil.close(reader);
        }
    }
}
